#include "GraphicsView.h"
#include "GraphicsItem.h"
#include "GraphicsLineItem.h"

GraphicsView::GraphicsView(QWindow *parent)
    : QWindow(parent)
    , m_context(0)
    , m_device(0)
{
    setSurfaceType(QWindow::OpenGLSurface);
}

GraphicsView::~GraphicsView()
{
    delete m_device;
}

bool GraphicsView::event(QEvent *event)
{
    switch (event->type()) {
    case QEvent::UpdateRequest:
        renderNow();
        return true;
    default:
        return QWindow::event(event);
    }
}

void GraphicsView::initialize()
{
//    GraphicsLineItem *it1 = new GraphicsLineItem();
//    it1->setLine(QPointF(-1.0,-1.0), QPointF(-1.0, 1.0));
//    addItem(it1);

    GraphicsLineItem *it2 = new GraphicsLineItem();
    it2->setLine(QPointF(-1.0,-1.0), QPointF(1.0, 1.0));
    addItem(it2);

    GraphicsLineItem *it3 = new GraphicsLineItem();
    it3->setLine(QPointF(-1.0,1.0), QPointF(1.0, -1.0));
    addItem(it3);

//    GraphicsLineItem *it4 = new GraphicsLineItem();
//    it4->setLine(QPointF(1.0,-1.0), QPointF(1.0, 1.0));
//    addItem(it4);

    if (!m_device)
        m_device = new QOpenGLPaintDevice;
    m_device->setSize(size());
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}

void GraphicsView::addItem(GraphicsItem * item)
{
    m_items.push_back(item);
}

void GraphicsView::removeItem(GraphicsItem * item)
{
    m_items.remove(item);
}

void GraphicsView::render()
{
    std::for_each(m_items.begin(), m_items.end(), [](GraphicsItem *it) { it->render(); });
}

void GraphicsView::renderNow()
{
    if (!isExposed())
        return;

    bool needsInitialize = false;

    if (!m_context) {
        m_context = new QOpenGLContext(this);
        m_context->setFormat(requestedFormat());
        m_context->create();

        needsInitialize = true;
    }

    m_context->makeCurrent(this);

    if (needsInitialize) {
        initializeOpenGLFunctions();
        initialize();
    }



    render();

    m_context->swapBuffers(this);
}

void GraphicsView::exposeEvent(QExposeEvent *event)
{
    Q_UNUSED(event);

    if (isExposed())
        renderNow();
}

void GraphicsView::setScene(GraphicsScene *sc)
{
    m_scene = sc;
}
